﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Input;
using Microsoft.Devices.Sensors;




namespace PicturePuzzle
{
    public partial class GamePage : PhoneApplicationPage
    {
        ContentManager contentManager;
        GameTimer timer;
        SpriteBatch spriteBatch;
        SpriteFont font;
        GraphicsDevice gd;

        Vector3 acceleration;
        Accelerometer accelerometer;
        Rectangle collision_Rect;

        Texture2D picture;

        const int x_parts = 2;
        const int y_parts = 5;

        PuzzlePiece[,] pieces = new PuzzlePiece[x_parts,y_parts];

        string text = "";
        string accelerationvalue = "";

        Point p = new Point(0, 0);

        public GamePage()
        {
            InitializeComponent();
            
            // Get the content manager from the application
            contentManager = (System.Windows.Application.Current as App).Content;

            // Create a timer for this page
            timer = new GameTimer();
            timer.UpdateInterval = TimeSpan.FromTicks(333333);
            timer.Update += OnUpdate;
            timer.Draw += OnDraw;
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // Set the sharing mode of the graphics device to turn on XNA renderin
            gd = SharedGraphicsDeviceManager.Current.GraphicsDevice;
            gd.SetSharingMode(true);

            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager.Current.GraphicsDevice);
            font = contentManager.Load<SpriteFont>("TMR");

            //Initialize Accelerometer
            if (Accelerometer.IsSupported)
            {
                if (accelerometer == null)
                {
                    // Instantiate the Accelerometer.
                    accelerometer = new Accelerometer();
                    accelerometer.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20);
                    accelerometer.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(accelerometer_CurrentValueChanged);
                }

                accelerometer.Start();
            }
            

            #region Define Touchpanel capabilities.
            TouchPanel.EnabledGestures = GestureType.FreeDrag | GestureType.Hold;

            #endregion


            picture = contentManager.Load<Texture2D>("Picture");

            #region Prepare the puzzle pieces.

            int w = picture.Bounds.Width/x_parts;
            int h = picture.Bounds.Height/y_parts;

            for (int i = 0; i < x_parts; i++)
            {
                for (int j = 0; j < y_parts; j++)
                {
                    pieces[i,j] = new PuzzlePiece(picture,
                        new Rectangle(i*w,j*h,w,h));
                }
            }

            #endregion

            //flip(pieces[0, 3], pieces[1, 2]);

            Random r = new Random();

            for(int i = 0; i < 25; i++)flip(pieces[r.Next(0,x_parts),r.Next(0,y_parts)], pieces[r.Next(0,x_parts),r.Next(0,y_parts)]);

            // TODO: use this.content to load your game content here

            // Start the timer
            timer.Start();

            base.OnNavigatedTo(e);
        }

        //Flip the positions.
        void flip(PuzzlePiece a, PuzzlePiece b)
        {
            Vector2 temp = a.position;
            a.position = b.position;
            b.position = temp;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            // Stop the timer
            timer.Stop();

            // Set the sharing mode of the graphics device to turn off XNA rendering
            gd.SetSharingMode(false);

            base.OnNavigatedFrom(e);
        }

        /// <summary>
        /// Allows the page to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        private void OnUpdate(object sender, GameTimerEventArgs e)
        {
            // TODO: Add your update logic here

            TouchCollection tc = TouchPanel.GetState();

            if (TouchPanel.IsGestureAvailable)
            {
                GestureSample g = TouchPanel.ReadGesture();

                if (g.GestureType == GestureType.FreeDrag && tc.Count > 0)
                {


                    for (int i = 0; i < x_parts; i++)
                    {
                        for (int j = 0; j < y_parts; j++)
                        {
                            if (pieces[i, j].destinationRect.Contains(new Point((int)tc[0].Position.X, (int)tc[0].Position.Y)))
                            {
                                p = new Point(i, j); break;
                            }
                        }
                    }

                    TouchLocation tl;
                    if (tc[0].TryGetPreviousLocation(out tl))
                    {

                        pieces[p.X, p.Y].position += new Vector2(tc[0].Position.X - tl.Position.X, tc[0].Position.Y - tl.Position.Y);

                    }

                }







                foreach (PuzzlePiece p in pieces) p.Update(e);
                text = "Piece position: " + pieces[0, 0].position;

            }



            text = tc.Count + " touches.";
            accelerationvalue = "Acceleration: " + acceleration.X + " " + acceleration.Y + " "
                + acceleration.Z;

            foreach (PuzzlePiece p in pieces)
            {
                p.velocity.X += acceleration.X * 10;
                p.velocity.Y += acceleration.Y * -10;
                p.Update(e);
            }
        }

        /// <summary>
        /// Allows the page to draw itself.
        /// </summary>
        private void OnDraw(object sender, GameTimerEventArgs e)
        {
            gd.Clear(Color.Black);

            spriteBatch.Begin();

            

            foreach (PuzzlePiece piece in pieces)
            {
                piece.Draw(spriteBatch);
            }

            spriteBatch.DrawString(font, text, new Vector2(10, 10), Color.White);
            spriteBatch.DrawString(font, accelerationvalue, new Vector2(10, 30), Color.White);

            spriteBatch.End();



            // TODO: Add your drawing code here
        }

        //Called on Accelerometer value change
        void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
        {
            acceleration = e.SensorReading.Acceleration;
            // Call UpdateUI on the UI thread and pass the AccelerometerReading.
            //Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading));
        }
        
    }
}